gtkplacessidebar: avoid unresponsive UI while trashing
authorCarlos Soriano <csoriano@gnome.org>
Thu, 25 Feb 2016 13:25:40 +0000 (14:25 +0100)
committerCarlos Soriano <csoriano@gnome.org>
Thu, 25 Feb 2016 13:44:40 +0000 (14:44 +0100)
We were updating the whole places sidebar when the trash changed.
This effectively removes all rows and create new ones for every trash
state change.

Although when using GtkTreeView it was somehow ok, with the new
implementation with GtkListBox this effectively locks the UI while the
trash operations are being performed.

When performing operations for i.e. 100 files, the UI can be locked
for more than 1 minute since gvfs-trash usually takes time.

To fix this just update the icon of the trash when the state of the
trash change instead of the whole sidebar.

https://bugzilla.gnome.org/show_bug.cgi?id=762677

gtk/gtkplacessidebar.c
gtk/gtksidebarrow.c
gtk/gtksidebarrowprivate.h

index 3de9e2cd66c0613e066ea1d3f79c52b7c4a3e49a..ba8d3c0241309dc5752bc1ed82c475673f11f2a0 100644 (file)
@@ -132,6 +132,7 @@ struct _GtkPlacesSidebar {
   gchar *rename_uri;
 
   gulong trash_monitor_changed_id;
+  GtkWidget *trash_row;
 
   /* DND */
   GList     *drag_list; /* list of GFile */
@@ -878,6 +879,14 @@ is_external_volume (GVolume *volume)
   return is_external;
 }
 
+static void
+update_trash_icon (GtkPlacesSidebar *sidebar)
+{
+  if (sidebar->trash_row)
+    gtk_sidebar_row_set_icon (GTK_SIDEBAR_ROW (sidebar->trash_row),
+                              _gtk_trash_monitor_get_icon (sidebar->trash_monitor));
+}
+
 static void
 update_places (GtkPlacesSidebar *sidebar)
 {
@@ -980,11 +989,11 @@ update_places (GtkPlacesSidebar *sidebar)
     {
       mount_uri = "trash:///"; /* No need to strdup */
       icon = _gtk_trash_monitor_get_icon (sidebar->trash_monitor);
-      add_place (sidebar, PLACES_BUILT_IN,
-                 SECTION_COMPUTER,
-                 _("Trash"), icon, mount_uri,
-                 NULL, NULL, NULL, 0,
-                 _("Open the trash"));
+      sidebar->trash_row = add_place (sidebar, PLACES_BUILT_IN,
+                                      SECTION_COMPUTER,
+                                      _("Trash"), icon, mount_uri,
+                                      NULL, NULL, NULL, 0,
+                                      _("Open the trash"));
       g_object_unref (icon);
     }
 
@@ -3773,7 +3782,7 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
 
   sidebar->trash_monitor = _gtk_trash_monitor_get ();
   sidebar->trash_monitor_changed_id = g_signal_connect_swapped (sidebar->trash_monitor, "trash-state-changed",
-                                                                G_CALLBACK (update_places), sidebar);
+                                                                G_CALLBACK (update_trash_icon), sidebar);
 
   gtk_widget_set_size_request (GTK_WIDGET (sidebar), 140, 280);
 
index a095bd26552364df6038b61dd5650bde28df6dfe..3df5b026dd4018b606566a8444af6ce8959b256f 100644 (file)
@@ -156,11 +156,7 @@ gtk_sidebar_row_set_property (GObject      *object,
       break;
 
     case PROP_ICON:
-      g_set_object (&self->icon, g_value_get_object (value));
-      if (self->icon != NULL)
-        gtk_image_set_from_gicon (GTK_IMAGE (self->icon_widget), self->icon, GTK_ICON_SIZE_MENU);
-      else
-        gtk_image_clear (GTK_IMAGE (self->icon_widget));
+      gtk_sidebar_row_set_icon (self, g_value_get_object (value));
       break;
 
     case PROP_LABEL:
@@ -239,7 +235,7 @@ gtk_sidebar_row_set_property (GObject      *object,
                                  (GtkCallback) gtk_widget_destroy,
                                  NULL);
 
-         context = gtk_widget_get_style_context (GTK_WIDGET (self));
+          context = gtk_widget_get_style_context (GTK_WIDGET (self));
           gtk_style_context_add_class (context, "sidebar-placeholder-row");
         }
       break;
@@ -283,6 +279,25 @@ gtk_sidebar_row_hide (GtkSidebarRow *self,
   gtk_revealer_set_transition_duration (GTK_REVEALER (self->revealer), transition_duration);
 }
 
+void
+gtk_sidebar_row_set_icon (GtkSidebarRow *self,
+                          GIcon         *icon)
+{
+  g_return_if_fail (GTK_IS_SIDEBAR_ROW (self));
+
+  if (self->icon != icon)
+    {
+      g_set_object (&self->icon, icon);
+      if (self->icon != NULL)
+        gtk_image_set_from_gicon (GTK_IMAGE (self->icon_widget), self->icon,
+                                  GTK_ICON_SIZE_MENU);
+      else
+        gtk_image_clear (GTK_IMAGE (self->icon_widget));
+
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ICON]);
+    }
+}
+
 static void
 gtk_sidebar_row_finalize (GObject *object)
 {
index 8042757c99cabf68fc4ab48099a70f503056732f..d13dc6d830ce59a7cd7784e6025afac837966a3a 100644 (file)
@@ -50,6 +50,8 @@ void           gtk_sidebar_row_reveal (GtkSidebarRow *self);
 
 GtkWidget     *gtk_sidebar_row_get_eject_button (GtkSidebarRow *self);
 GtkWidget     *gtk_sidebar_row_get_event_box    (GtkSidebarRow *self);
+void           gtk_sidebar_row_set_icon         (GtkSidebarRow *self,
+                                                 GIcon         *icon);
 
 G_END_DECLS